package com.hns.phone.maintenance.service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hns.can.base.entity.SysUserEntity;
import com.hns.can.common.constants.GlobalConst;
import com.hns.can.common.formula.FillCodeDscValue;
import com.hns.can.common.formula.FillParamsVo;
import com.hns.frame.enumrate.MsgType;
import com.hns.frame.exception.BusinessException;
import com.hns.frame.mybatis.Pagination;
import com.hns.frame.service.CommonService;
import com.hns.phone.common.vo.PhoneParamsVo;
import com.hns.phone.entity.AppCarMaintenInfoEntity;
import com.hns.phone.entity.AppCarMaintenRmndrInfoEntity;
import com.hns.phone.maintenance.vo.ExaminReportDetailVo;
import com.hns.phone.maintenance.vo.ExaminReportVo;
import com.hns.phone.maintenance.vo.MaintenanceParamVo;
import com.hns.phone.maintenance.vo.MaintenanceRecordVo;
import com.hns.phone.maintenance.vo.MaintenanceReportParamVo;
import com.hns.tool.pub.PubUtil;

@Service
public class PhoneCarMaintService extends CommonService {
	@Autowired
    private FillCodeDscValue codeDscValue;
	
	@SuppressWarnings("rawtypes")
	private void fillDscValue(List appCarMaintenInfoResultList)
			throws Exception {
		Map<String,String> map = new HashMap<String,String>();
        map.put("licPltNo",  GlobalConst.DEFAULT_CACHE_VALUE);
        FillParamsVo vo1 = new FillParamsVo("carId", map);
        map = new HashMap<String,String>();
        map.put("lineName",  GlobalConst.DEFAULT_CACHE_VALUE);
        FillParamsVo vo2 = new FillParamsVo("lineId", map);
        codeDscValue.fillInfoValue(appCarMaintenInfoResultList,
        		new String[] {GlobalConst.CACHE_KEY_BASE_LINE_INFO, GlobalConst.CACHE_KEY_BASE_CAR_INFO}, vo1, vo2);
	}
	
	/**
	 * 查询维保计划
	 * @param conditionVo
	 * @param request
	 * @return
	 * @throws Exception
	 * @author:yecb
	 * @email:lps00@163.com
	 */
	@SuppressWarnings({ "unchecked"})
    @Transactional
    public Pagination searchMaintenancePage(MaintenanceParamVo conditionVo) throws Exception {
		List appCarMaintenInfoResultList=searchMaintenanceList(conditionVo);
	    Pagination page = new Pagination( this.getRowBounds(), appCarMaintenInfoResultList.size());
	    page.setData(appCarMaintenInfoResultList);
        return page;
    }
	
	public List<AppCarMaintenInfoEntity> getSoloMaintenanceInfo(MaintenanceParamVo conditionVo) throws Exception {
		List<AppCarMaintenInfoEntity> list = PubUtil.convertListMapToObject(this.sqlMapDao.selectList("phoneCarMaintePlan.soloMaintenanceInfo", conditionVo), AppCarMaintenInfoEntity.class);
		fillDscValue(list);
		return list;
	}
	
	/**
	 * 查询维保过期
	 * @param conditionVo
	 * @param request
	 * @return
	 * @throws Exception
	 * @author:yecb
	 * @email:lps00@163.com
	 */
	@SuppressWarnings({ "unchecked"})
    @Transactional
    public List searchMaintenanceList(MaintenanceParamVo conditionVo) throws Exception {
		//1.通过维保明细查询出维保计划
		List<AppCarMaintenInfoEntity> appCarMaintenInfoList = getMaintenancePlan(conditionVo);
		//2.查询维保设置
		List appCarMaintenRmndrInfoList = getMaintenanceSetting(conditionVo);
		//3.获取不同车型的维保设置信息(key:车型;value:对应的维保类型列表)
		HashMap<String,ArrayList<AppCarMaintenRmndrInfoEntity>> appCarMaintenRmndrInfoMap=getCarMaintenRmndrInfoByCarTypeMap(appCarMaintenRmndrInfoList);
		List appCarMaintenInfoResultList=new ArrayList();
		//4.根据维保计划里面的车辆类型，确定该车型的维保类别，然后计算出需要的维保里程以及维保时间
		for(AppCarMaintenInfoEntity appCarMaintenInfoEntity: appCarMaintenInfoList){
			ArrayList<AppCarMaintenRmndrInfoEntity> appTypesList=appCarMaintenRmndrInfoMap.get(appCarMaintenInfoEntity.getCarType());
			if(PubUtil.isEmpty(appTypesList)||PubUtil.isEmpty(appCarMaintenInfoEntity.getTotalMile())){
				continue;
			}
			AppCarMaintenRmndrInfoEntity appCarMaintenRmndrInfoResult=null;
			//4.1确定该车型的维保类别appCarMaintenRmndrInfoResult，间隔差最小值才是我们需要进行的维保类别
			for(AppCarMaintenRmndrInfoEntity appCarMaintenRmndrInfoEntity:appTypesList){
				Double interMile=(appCarMaintenInfoEntity.getTotalMile().doubleValue()-appCarMaintenInfoEntity.getLastMaintenMile().doubleValue());
				if(appCarMaintenRmndrInfoEntity.getItrvMile().doubleValue()<=interMile){
					appCarMaintenRmndrInfoResult=appCarMaintenRmndrInfoEntity;
				}
			}
			if(appCarMaintenRmndrInfoResult==null){
				continue;
			}
			//4.2计算出需要的维保里程以及维保时间
			getMaintenanceMileAndTime(appCarMaintenInfoEntity, appCarMaintenRmndrInfoResult);
			//过滤条件,过滤剩余里程，剩余天数满足条件的
			Double remainMile = appCarMaintenInfoEntity.getRemainMile();
			Long remainTime = appCarMaintenInfoEntity.getRemainTime();
			if(remainMile>0 || remainTime>0){//如果还有剩余里程或者当前时间没有达到维保日期，说明没有维保过期
				continue;
			}
			appCarMaintenInfoResultList.add(appCarMaintenInfoEntity);
		}
		fillDscValue(appCarMaintenInfoResultList);
        return appCarMaintenInfoResultList;
    }

	/**
	 * 获取不同车型的维保设置信息
	 * @param appCarMaintenRmndrInfoList 维保设置LIST
	 * @return HashMap<String,ArrayList<AppCarMaintenRmndrInfoEntity>> key:车辆类型；value:对应的设置列表
	 * @author:yecb
	 * @email:lps00@163.com
	 */
	private HashMap<String,ArrayList<AppCarMaintenRmndrInfoEntity>> getCarMaintenRmndrInfoByCarTypeMap(List<AppCarMaintenRmndrInfoEntity> appCarMaintenRmndrInfoList){
		HashMap<String,ArrayList<AppCarMaintenRmndrInfoEntity>> appCarMaintenRmndrInfoMap=new HashMap<String,ArrayList<AppCarMaintenRmndrInfoEntity>>();
		for(AppCarMaintenRmndrInfoEntity appCarMaintenRmndrInfoEntity:appCarMaintenRmndrInfoList){
			ArrayList<AppCarMaintenRmndrInfoEntity> appTypesList=appCarMaintenRmndrInfoMap.get(appCarMaintenRmndrInfoEntity.getCarType());
			if(PubUtil.isEmpty(appTypesList)){
				ArrayList<AppCarMaintenRmndrInfoEntity> appTypeList=new ArrayList<AppCarMaintenRmndrInfoEntity>();
				appTypeList.add(appCarMaintenRmndrInfoEntity);
				appCarMaintenRmndrInfoMap.put(appCarMaintenRmndrInfoEntity.getCarType(), appTypeList);
			}else{
				appTypesList.add(appCarMaintenRmndrInfoEntity);
			}
		}
		return appCarMaintenRmndrInfoMap;
	}

	/**
	 * 获取维保记录
	 * @param param
	 * @return
	 * @author:zhangyu
	 * @email:zhangyu2222z@sina.cn
	 */
	public Pagination getMaintenanceRecord(MaintenanceParamVo param) {
		Pagination page = this.myBatisPage("phoneCarMaintePlan.getMaintenanceCount", "phoneCarMaintePlan.getMaintenanceRecord", param, MaintenanceRecordVo.class);
		return page;
	}
	
	@Transactional
    public Pagination getLastExaminReport(SysUserEntity sysUserEntity) throws Exception {
    	MaintenanceReportParamVo conditionVo=new MaintenanceReportParamVo();
    	conditionVo.setCorpId(sysUserEntity.getCorpId());
    	Pagination page = this.myBatisPage("phoneEaxminReport.getLastExaminReportCount", "phoneEaxminReport.getLastExaminReport", conditionVo, ExaminReportVo.class);
    	List<Object> list = page.getData();
    	Map<String,String> map = new HashMap<String,String>();
    	map.put("licPltNo",  GlobalConst.DEFAULT_CACHE_VALUE);
    	FillParamsVo fillParamsCarVo = new FillParamsVo("carId", map);
    	map = new HashMap<String,String>();
    	map.put("lineName", GlobalConst.DEFAULT_CACHE_VALUE);
    	FillParamsVo fillParamsLineVo = new FillParamsVo("lineId", map);
    	codeDscValue.fillInfoValue(list,new String[] {GlobalConst.CACHE_KEY_BASE_CAR_INFO,GlobalConst.CACHE_KEY_BASE_LINE_INFO}, fillParamsCarVo,fillParamsLineVo);
    	page.setData(list);
    	return page;
    }

	
	public List<ExaminReportDetailVo> getExaminReportDetail(PhoneParamsVo vo) {
		List<ExaminReportDetailVo> list = PubUtil.convertListMapToObject(this.sqlMapDao.selectList("phoneEaxminReport.getExaminReportDetail", vo), ExaminReportDetailVo.class);
		return list;
	}

	public List getMaintenancePlanList(MaintenanceParamVo conditionVo) throws Exception {
		//1.通过维保明细查询出维保计划
		List<AppCarMaintenInfoEntity> appCarMaintenInfoList = getMaintenancePlan(conditionVo);
		// 2.查询维保设置
		List appCarMaintenRmndrInfoList = getMaintenanceSetting(conditionVo);
		
		List appCarMaintenInfoResultList = new ArrayList();
		// 3.获取不同车型的维保设置信息(key:车型;value:对应的维保类型列表)
		if(PubUtil.isNotEmpty(appCarMaintenRmndrInfoList)){
			HashMap<String, ArrayList<AppCarMaintenRmndrInfoEntity>> appCarMaintenRmndrInfoMap = getCarMaintenRmndrInfoByCarTypeMap(appCarMaintenRmndrInfoList);
			// 4.根据维保计划里面的车辆类型，确定该车型的维保类别，然后计算出需要的维保里程以及维保时间
			for (AppCarMaintenInfoEntity appCarMaintenInfoEntity : appCarMaintenInfoList) {
				ArrayList<AppCarMaintenRmndrInfoEntity> appTypesList = appCarMaintenRmndrInfoMap.get(appCarMaintenInfoEntity.getCarType());
				if (PubUtil.isEmpty(appTypesList)|| PubUtil.isEmpty(appCarMaintenInfoEntity.getTotalMile())) {
					continue;
				}
				Double minItrvMile = 99999999999.9; // 最小间隔里程
				AppCarMaintenRmndrInfoEntity appCarMaintenRmndrInfoResult = null;
				// 4.1确定该车型的维保类别appCarMaintenRmndrInfoResult，间隔差最小值才是我们需要进行的维保类别
				for (AppCarMaintenRmndrInfoEntity appCarMaintenRmndrInfoEntity : appTypesList) {
					Double interMile = (appCarMaintenInfoEntity.getTotalMile().doubleValue() - appCarMaintenInfoEntity.getMaintenMile().doubleValue());
					if (appCarMaintenRmndrInfoEntity.getItrvMile().doubleValue() >= interMile) {
						Double minItrvMileTemp = appCarMaintenRmndrInfoEntity.getItrvMile().doubleValue() - interMile;// 计算里程间隔的最小差值
						if (minItrvMileTemp < minItrvMile) {
							minItrvMile = minItrvMileTemp;
							appCarMaintenRmndrInfoResult = appCarMaintenRmndrInfoEntity;
						}
					}
				}
				if (appCarMaintenRmndrInfoResult == null) {
					continue;
				}
				// 4.2计算出需要的维保里程以及维保时间
				getMaintenanceMileAndTime(appCarMaintenInfoEntity, appCarMaintenRmndrInfoResult);
				// 过滤条件,过滤剩余里程，剩余天数满足条件的
				Double remainMile = appCarMaintenInfoEntity.getRemainMile();
				Long remainTime = appCarMaintenInfoEntity.getRemainTime();
				if (!PubUtil.isEmpty(conditionVo.getRemainDay())) {
					if (remainTime > conditionVo.getRemainDay()) {
						continue;
					}
				}
				if (!PubUtil.isEmpty(conditionVo.getRemainMile())) {
					if (remainMile > (conditionVo.getRemainMile() * 1000)) {
						continue;
					}
				}
				appCarMaintenInfoResultList.add(appCarMaintenInfoEntity);
			}
			Map<String, String> map = new HashMap<String, String>();
			map.put("licPltNo", GlobalConst.DEFAULT_CACHE_VALUE);
			FillParamsVo vo = new FillParamsVo("carId", map);
			codeDscValue.fillInfoValue(appCarMaintenInfoResultList,
					new String[] { GlobalConst.CACHE_KEY_BASE_CAR_INFO }, vo);
		}
		return appCarMaintenInfoResultList;
	}
	
	
	private List<AppCarMaintenInfoEntity> getMaintenancePlan(MaintenanceParamVo conditionVo){
		List<AppCarMaintenInfoEntity> appCarMaintenInfoList = PubUtil.convertListMapToObject(this.sqlMapDao.selectList("phoneCarMaintePlan.getMaintenPlanList", conditionVo), AppCarMaintenInfoEntity.class);
		if(PubUtil.isEmpty(appCarMaintenInfoList)){
			 throw new BusinessException(MsgType.WARN.getFlag(),"没有维保计划信息，无法查询出维保计划！");
		}
		return appCarMaintenInfoList;
	}
	
	
	private List getMaintenanceSetting(MaintenanceParamVo conditionVo){
		List appCarMaintenRmndrInfoList = PubUtil.convertListMapToObject(this.sqlMapDao.selectList("phoneCarMaintePlan.getMaintenRmndrInfo", conditionVo), AppCarMaintenRmndrInfoEntity.class);
		if(PubUtil.isEmpty(appCarMaintenRmndrInfoList)){
			throw new BusinessException(MsgType.WARN.getFlag(),"没有维保设置信息，无法查询出维保计划！");
		}
		Map<String,String> mapValue = new HashMap<String,String>();
	    mapValue.put("mntType", "MAIN1000");
	    codeDscValue.fillCodeDscValue(appCarMaintenRmndrInfoList, mapValue);
	    return appCarMaintenRmndrInfoList;
	}
	
	private void getMaintenanceMileAndTime(AppCarMaintenInfoEntity appCarMaintenInfoEntity, 
			AppCarMaintenRmndrInfoEntity appCarMaintenRmndrInfoResult) throws Exception{
		appCarMaintenInfoEntity.setPlanMaintenMile(new BigDecimal(appCarMaintenInfoEntity.getMaintenMile().doubleValue()+appCarMaintenRmndrInfoResult.getItrvMile().doubleValue()));//计划保养里程(上次维保里程+ 保养间隔里程)
		appCarMaintenInfoEntity.setMaintenCgy(appCarMaintenRmndrInfoResult.getMntType());//计划维保类别
		appCarMaintenInfoEntity.setPartsCode(appCarMaintenRmndrInfoResult.getPartsCode());//建议更换零部件
		Double remainMile=appCarMaintenInfoEntity.getMaintenMile().doubleValue()
				+appCarMaintenRmndrInfoResult.getItrvMile().doubleValue()
				-appCarMaintenInfoEntity.getTotalMile().doubleValue();//剩余里程(上次维保里程+间隔里程 - 总里程)
		DecimalFormat    df   = new DecimalFormat("######0.00");  
		appCarMaintenInfoEntity.setRemainMile(Double.valueOf(df.format(remainMile)));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
        Calendar cd = Calendar.getInstance();   
        cd.setTime(sdf.parse(appCarMaintenInfoEntity.getLastMaintenDate()));
        cd.add(Calendar.MONTH, appCarMaintenRmndrInfoResult.getItrvTime().intValue());//增加一个月
		appCarMaintenInfoEntity.setPlanMaintenDate(sdf.format(cd.getTime()));// 计算计划保养日期（车辆上次维保日期 + 间隔日期）
		Long remainTime=(cd.getTime().getTime()-new Date().getTime())/(24*60*60*1000);// 剩余天数（车辆上次维保日期 + 间隔日期 - 当前日期）
		appCarMaintenInfoEntity.setRemainTime(remainTime);
		//return appCarMaintenInfoEntity;
	}
	
	
}
